﻿
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using Snake.ORM.Reflection;
using System.Reflection;

using SnakeSimpleSqlTests.Model;

namespace SnakeSimpleSqlTests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class ObjectCreationTests
    {
        public ObjectCreationTests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestDynamicMethodObjectCreation()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            //InstanceCreateHandler instance = DynamicMethodCompiler.CreateInstance<Person>();
            //Person person = (Person)instance.Invoke();
            //TimeSpan ts = watch.Elapsed;
            //long ms = watch.ElapsedMilliseconds;
            //watch.Stop();
            //string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            //                                     ts.Hours
            //                                     , ts.Minutes
            //                                     , ts.Seconds
            //                                     , (ts.Milliseconds / 10));
            //Console.WriteLine("Dynamic Method Elapsed Time: {0}, In Milliseconds: {1} ", elapsedTime, ms.ToString());


            //Assert.IsNotNull(person);
            //person.FirstName = "Delegate";
            //person.LastName = "Created";
            //person.Address = "101 Representative Street";
            //Console.WriteLine("Person: {0}", person.ToString());

        }

        [TestMethod]
        public void TestStandardObjectCreation()
        {
            //System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            //watch.Start();
            //Person person = new Person();
            //TimeSpan ts = watch.Elapsed;
            //long ms = watch.ElapsedMilliseconds;
            //watch.Stop();
            //string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            //                                     ts.Hours
            //                                     , ts.Minutes
            //                                     , ts.Seconds
            //                                     , (ts.Milliseconds / 10));
            //Console.WriteLine("Dynamic Method Elapsed Time: {0}, In Milliseconds: {1} ", elapsedTime, ms.ToString());

            //Assert.IsNotNull(person);
            //person.FirstName = "Charles";
            //person.LastName = "Taylor";
            //person.Address = "133 Biscuit Way";
            //Console.WriteLine("Person: {0}", person.ToString());

        }

        [TestMethod]
        public void TestReflectionObjectCreation()
        {
            //Stopwatch watch = new Stopwatch();
            //watch.Start();
            //Type personType = typeof(Person);
            //ConstructorInfo constructor = personType.GetConstructor(System.Type.EmptyTypes);
            //Person person = (Person)constructor.Invoke(new object[0]);
            //TimeSpan ts = watch.Elapsed;
            //long ms = watch.ElapsedMilliseconds;
            //watch.Stop();
            //string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            //                                     ts.Hours
            //                                     , ts.Minutes
            //                                     , ts.Seconds
            //                                     , (ts.Milliseconds / 10));
            //Console.WriteLine("Dynamic Method Elapsed Time: {0}, In Milliseconds: {1} ", elapsedTime, ms.ToString());

            //Assert.IsNotNull(person);
            //person.FirstName = "Charles";
            //person.LastName = "Taylor";
            //person.Address = "133 Biscuit Way";
            //Console.WriteLine("Person: {0}", person.ToString());

        }

        [TestMethod]
        public void TestCallObjectCreationWrapper()
        {
            //Person person = ObjCreation.CreateInstance<Person>();
            //Assert.IsNotNull(person);
            //person.FirstName = "Halle";
            //person.LastName = "Berry";
            //person.Address = "456 Hollywood Blvd.";
            //Console.WriteLine("Person: {0}", person.ToString());
        }

        [TestMethod]
        public void TestPropertySetter()
        {

            //Person person = new Person();
            //PropertyInfo prop = person.GetType().GetProperty("FirstName",
            //                                                 BindingFlags.Public |
            //                                                 BindingFlags.NonPublic |
            //                                                 BindingFlags.Instance);
            //SetPropertyHandler setHandle = DynamicMethodCompiler.CreateSetPropertyHandler<Person>(prop);
            //setHandle(person, "John");
            //Assert.AreEqual(person.FirstName, "John");
            //Console.WriteLine("Person First Name is: {0} ", person.FirstName);
        }

        [TestMethod]
        public void TestPropertyGetter()
        {

            //Person person = new Person();
            //person.FirstName = "Jacob";
            //PropertyInfo prop = person.GetType().GetProperty("FirstName",
            //                                                 BindingFlags.Public |
            //                                                 BindingFlags.NonPublic |
            //                                                 BindingFlags.Instance);
            //GetPropertyHandler getHandle = DynamicMethodCompiler.CreatePropertyGetHandler<Person>(prop);
            //String FirstName = (String)getHandle(person);
            //Assert.AreEqual(FirstName, "Jacob");
            //Console.WriteLine("Person First Name is: {0} ", person.FirstName);
        }


        [TestMethod]
        public void TestPropertyGetterValueTypes()
        {

            //Stats stats = new Stats()
            //{
            //    Count = 100,
            //    IsComplete = true,
            //    StatsTitle = "Cool Stats",
            //    TotalNumber = 3000
            //};

            //PropertyInfo prop = stats.GetType().GetProperty("Count",
            //                                                 BindingFlags.Public |
            //                                                 BindingFlags.NonPublic |
            //                                                 BindingFlags.Instance);
            //GetPropertyHandler getHandle = DynamicMethodCompiler.CreatePropertyGetHandler<Stats>(prop);
            //int count = (int)getHandle(stats);
            //Assert.AreEqual(count, 100);

            //PropertyInfo prop2 = stats.GetType().GetProperty("IsComplete",
            //                                                 BindingFlags.Public |
            //                                                 BindingFlags.NonPublic |
            //                                                 BindingFlags.Instance);
            //GetPropertyHandler getHandle2 = DynamicMethodCompiler.CreatePropertyGetHandler<Stats>(prop2);
            //bool isComplete = (bool)getHandle2(stats);
            //Assert.AreEqual(isComplete, true);


            //PropertyInfo prop3 = stats.GetType().GetProperty("StatsTitle",
            //                                                 BindingFlags.Public |
            //                                                 BindingFlags.NonPublic |
            //                                                 BindingFlags.Instance);
            //GetPropertyHandler getHandle3 = DynamicMethodCompiler.CreatePropertyGetHandler<Stats>(prop3);
            //string statsTitle = (string)getHandle3(stats);
            //Assert.AreEqual(statsTitle, "Cool Stats");

            //PropertyInfo prop4 = stats.GetType().GetProperty("TotalNumber",
            //                                                 BindingFlags.Public |
            //                                                 BindingFlags.NonPublic |
            //                                                 BindingFlags.Instance);
            //GetPropertyHandler getHandle4 = DynamicMethodCompiler.CreatePropertyGetHandler<Stats>(prop4);
            //long totalNumber = (long)getHandle4(stats);
            //Assert.AreEqual(totalNumber, 3000);

            //Console.WriteLine("Stats contains Count: {0}, Title {1}, TotalNumber {2}, IsComplete {3} ", count, statsTitle, totalNumber, isComplete);
        }
    }
}
